<?php declare(strict_types=1);
/**
 * @author      xianganyall <xianganyall@gmail.com>
 * @copyright   2023-2025 owner
 **/

namespace Srv\Libs\Plugins\Protos;

use Google\Protobuf\ListValue;
use Google\Protobuf\Value;

class ProtoListValue
{
    /**
     * @param array $strList
     * @param bool $strict
     * @param bool $isFail
     * @return ListValue
     * genStringListValue
     */
    public static function genStringListValue(array $strList, bool $strict = false, bool &$isFail = false):ListValue
    {
        $isFail                 = false;
        $ListValue              = new ListValue();
        if(count($strList) < 1){
            $isFail             = true;
            return $ListValue;
        }
        $ValueItemList          = [];
        foreach ($strList as $strItem){
            if(!is_string($strItem)){
                if(!$strict){
                    $isFail     = true;
                    return $ListValue;
                }
                $strItem        = strval($strItem);
            }
            $ValueItemList[]    = ProtoValue::genStringValue($strItem);
        }
        $ListValue->setValues($ValueItemList);
        return $ListValue;
    }

    /**
     * @param array $numberList
     * @param bool $strict
     * @param bool $isFail
     * @return ListValue
     * genNumberListValue
     */
    public static function genNumberListValue(array $numberList, bool $strict = false, bool &$isFail = false):ListValue
    {
        $isFail                 = false;
        $ListValue              = new ListValue();
        if(count($numberList) < 1){
            $isFail             = true;
            return $ListValue;
        }
        $ValueItemList          = [];
        foreach ($numberList as $numberItem){
            if(is_int($numberItem)){
                $ValueItemList[]        = ProtoValue::genNumberIntValue($numberItem);
            }else if(is_float($numberItem)){
                $ValueItemList[]        = ProtoValue::genNumberFloatValue($numberItem);
            }else if(is_numeric($numberItem) && is_string($numberItem)){
                $ValueItemList[]        = ProtoValue::genNumberStrValue($numberItem);
            }else{
                if(!$strict || !is_string($numberItem)){
                    $isFail             = true;
                    return $ListValue;
                }
                if(preg_match('/^\d+\.\d+$/', $numberItem) > 0){
                    $numberItem         = floatval($numberItem);
                    $ValueItemList[]    = ProtoValue::genNumberFloatValue($numberItem);
                }else{
                    $numberItem         = intval($numberItem);
                    $ValueItemList[]    = ProtoValue::genNumberIntValue($numberItem);
                }
            }
        }
        $ListValue->setValues($ValueItemList);
        return $ListValue;
    }

    /**
     * @param array $boolList
     * @param bool $strict
     * @param bool $isFail
     * @return ListValue
     * genBoolListValue
     */
    public static function genBoolListValue(array $boolList, bool $strict = false, bool &$isFail = false):ListValue
    {
        $isFail                 = false;
        $ListValue              = new ListValue();
        if(count($boolList) < 1){
            $isFail             = true;
            return $ListValue;
        }
        $ValueItemList          = [];
        foreach ($boolList as $boolItem){
            if(!is_bool($boolItem)){
                if(!$strict){
                    $isFail     = true;
                    return $ListValue;
                }
                $boolItem       = boolval($boolItem);
            }
            $ValueItemList[]    = ProtoValue::genBoolValue($boolItem);
        }
        $ListValue->setValues($ValueItemList);
        return $ListValue;
    }

    /**
     * @param int $size
     * @param bool $isFail
     * @return ListValue
     * genNullListValue
     */
    public static function genNullListValue(int $size, bool &$isFail = false):ListValue
    {
        $isFail                 = false;
        $ListValue              = new ListValue();
        if($size < 1){
            $isFail             = true;
            return $ListValue;
        }
        $ValueItemList          = [];
        while(--$size >= 0){
            $ValueItemList[]    = ProtoValue::genNullValue();
        }
        $ListValue->setValues($ValueItemList);
        return $ListValue;
    }

    /**
     * @param ListValue $ListValue
     * @return Value
     * genValueListValue
     */
    public static function genValueListValue(ListValue $ListValue):Value
    {
        $ValueListValue         = new Value();
        $ValueListValue->setListValue($ListValue);
        return $ValueListValue;
    }

    /**
     * @param array $strList
     * @param bool $strict
     * @param bool $isFail
     * @return Value
     * genStringValueListValue
     */
    public static function genStringValueListValue(array $strList, bool $strict = false, bool &$isFail = false):Value
    {
        return self::genValueListValue(self::genStringListValue($strList, $strict, $isFail));
    }

    /**
     * @param array $numberList
     * @param bool $strict
     * @param bool $isFail
     * @return Value
     * genNumberValueListValue
     */
    public static function genNumberValueListValue(array $numberList, bool $strict = false, bool &$isFail = false):Value
    {
        return self::genValueListValue(self::genStringListValue($numberList, $strict, $isFail));
    }

    /**
     * @param array $boolList
     * @param bool $strict
     * @param bool $isFail
     * @return Value
     * genBoolValueListValue
     */
    public static function genBoolValueListValue(array $boolList, bool $strict = false, bool &$isFail = false):Value
    {
        return self::genValueListValue(self::genStringListValue($boolList, $strict, $isFail));
    }

    /**
     * @param int $size
     * @param bool $isFail
     * @return Value
     * genNullValueListValue
     */
    public static function genNullValueListValue(int $size, bool &$isFail = false):Value
    {
        return self::genValueListValue(self::genNullListValue($size, $isFail));
    }
}